package practica1.ui;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import practica1.Practica1;
import practica1.controller.Controller;
import practica1.controller.ControllerPoblacionAdapter;
import practica1.controller.ControllerPoblacionEvent;
import practica1.language.Language;
import practica1.language.LanguageEvent;
import practica1.language.LanguageListener;
import practica1.logic.LogicPoblacion;
import practica1.ui.panelPoblacion.PanelPoblacion;

/**
 * Componente que muestra todas las poblaciones en pantalla mediante un JTabbedPane
 * @author Miguel González - Ceura
 */
public class PanelPoblaciones extends JPanel implements LanguageListener {
    
    private JTabbedPane tabPaned;
    private Controller controlador;
    
    /**
     * Constructor por defecto del panel
     */
    public PanelPoblaciones() {
        controlador = Controller.getInstance();
        
        init();
        
        initListeners();
    }
    
    private void initListeners() {
        Language.getI().addLanguageListener(this);
        
        controlador.addControllerPoblacionListener(new EscuchadorPoblaciones());
        
        tabPaned.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                if(tabPaned.getTabCount() == 0) {
                    Practica1.getInstance().setTitle(
                            Language.getI().getP("PRACTICA_1"));
                } else {
                    Practica1.getInstance().setTitle(
                            Language.getI().getP("PRACTICA_1") + " - " + 
                        ((PanelPoblacion)tabPaned.getSelectedComponent()).
                        getPoblacion().getExperimentoPadre().
                        getNombreExperimento());
                }
            }
        });
    }
    
    /**
     * Inicializa los componentes Swing
     */
    private void init() {
        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        
        tabPaned = new JTabbedPane();
        
        add(tabPaned);
    }

    /**
     * Clase que se encarga de escuchar las poblaciones del controlador
     */
    private class EscuchadorPoblaciones extends ControllerPoblacionAdapter {
        /**
         * Método que es notificado cuando se quiere abrir una población, es decir,
         * mostrarse en pantalla
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void abiertaPoblacion(ControllerPoblacionEvent event) {
            LogicPoblacion poblacion = event.getPoblacion();
            PanelPoblacion panelNuevo = new PanelPoblacion(poblacion);
            
            tabPaned.addTab(poblacion.getNombrePoblacion()
                    , null, panelNuevo,
                            Language.getI().getP("DATOS_POBLACION"));

            tabPaned.setSelectedIndex(tabPaned.getTabCount() - 1);
        }

        /**
         * Método que es llamado al cerrar una población, es decir, se quiere
         * dejar de mostrar
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void cerradaPoblacion(ControllerPoblacionEvent event) {
            //Número del panel a eliminar
            int nPanelEl = -1;
            
            //Buscamos el panel de la población y lo quitamos
            for(int i=0; i<tabPaned.getTabCount() && nPanelEl == -1; i++) {
                LogicPoblacion poblacionPanel = ((PanelPoblacion)tabPaned
                        .getComponent(i)).getPoblacion();
                if(poblacionPanel.equals(
                        event.getPoblacion())) {
                    //Es el panel que queremos eliminar
                    nPanelEl = i;
                }
            }
            
            if(nPanelEl != -1) {
                tabPaned.remove(nPanelEl);
            }
        }
        
        /**
         * Método que es llamado cuando se quita una población, se deja de
         * mostrar
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void removedPoblacion(ControllerPoblacionEvent event) {
            //Número del panel a eliminar
            int nPanelEl = -1;
            
            //Buscamos el panel de la población y lo quitamos
            for(int i=0; i<tabPaned.getTabCount() && nPanelEl == -1; i++) {
                LogicPoblacion poblacionPanel = ((PanelPoblacion)tabPaned
                        .getComponent(i)).getPoblacion();
                if(poblacionPanel.equals(
                        event.getPoblacion())) {
                    //Es el panel que queremos eliminar
                    nPanelEl = i;
                }
            }
            
            //Si hemos encontrado el panel
            if(nPanelEl != -1) {
                tabPaned.remove(nPanelEl);
            }
        }

        /**
         * Método que es llamado cuando se quiere mostrar una población, se
         * cambia a la pestaña que la contiene
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void mostrarPoblacion(ControllerPoblacionEvent event) {
            //Número del panel a mostrar
            int nPanelMostrar = -1;
            
            //Buscamos el panel de la población y lo mostramos
            for(int i=0; i<tabPaned.getTabCount() && nPanelMostrar == -1; i++) {
                LogicPoblacion poblacionPanel = ((PanelPoblacion)tabPaned
                        .getComponent(i)).getPoblacion();
                if(poblacionPanel.equals(
                        event.getPoblacion())) {
                    //Es el panel que queremos eliminar
                    nPanelMostrar = i;
                }
            }
            
            if(nPanelMostrar != -1) {
                tabPaned.setSelectedIndex(nPanelMostrar);
            }
        }
        
        /**
         * Método que es llamado cuando se modifica una población, se encarga
         * de repintar el nombre de la pestaña con el nombre de la población
         * por si ha cambiado
         * @param event ControllerPoblacionEvent 
         */
        @Override
        public void modifiedPoblacion(ControllerPoblacionEvent event) {
            //Número del panel a mostrar
            int nPanel = -1;
            
            //Buscamos el panel de la población y cambianos el nombre de su tab
            for(int i=0; i<tabPaned.getTabCount() && nPanel == -1; i++) {
                LogicPoblacion poblacionPanel = ((PanelPoblacion)tabPaned
                        .getComponent(i)).getPoblacion();
                if(poblacionPanel.equals(
                        event.getPoblacion())) {
                    //Es el panel que queremos eliminar
                    nPanel = i;
                }
            }
            
            if(nPanel != -1) {
                tabPaned.setTitleAt(nPanel, event.getPoblacion().
                    getNombrePoblacion());
            }
        }
    }
    
    /**
     * Método que es llamado cuando el idioma de la aplicación cambia
     * @param evt LanguageEvent
     */
    @Override
    public void idiomaChange(LanguageEvent evt) {
        if(tabPaned.getTabCount() == 0) {
            Practica1.getInstance().setTitle(
                Language.getI().getP("PRACTICA_1"));
        } else {
            Practica1.getInstance().setTitle(
                Language.getI().getP("PRACTICA_1") + " - " + 
                ((PanelPoblacion)tabPaned.getSelectedComponent()).
                getPoblacion().getExperimentoPadre().
                getNombreExperimento());
        }
        
        for(int i=0; i<tabPaned.getTabCount(); i++) {
            tabPaned.setTitleAt(i, Language.getI().getP("DATOS_POBLACION"));
        }
    }
}
